<template>
  <div class="home-view">
    <!-- 页面头部 -->
    <div class="page-header">
      <div class="header-content">
        <h1 class="page-title">首页</h1>
        <p class="page-description">
          这是一个展示如何使用动态加载组件的示例页面。页面中的组件都是通过动态模块加载系统加载的。
        </p>
      </div>
      <div class="header-actions">
        <el-button-group>
          <el-button type="primary" @click="loadAllComponents" :loading="loadingAll">
            <el-icon><Download /></el-icon>
            加载所有组件
          </el-button>
          <el-button @click="unloadAllComponents" :loading="unloadingAll">
            <el-icon><Upload /></el-icon>
            卸载所有组件
          </el-button>
          <el-button @click="refreshAllComponents">
            <el-icon><Refresh /></el-icon>
            刷新所有组件
          </el-button>
        </el-button-group>
      </div>
    </div>

    <!-- 组件状态概览 -->
    <div class="status-overview">
      <el-row :gutter="20">
        <el-col :span="6">
          <el-card class="status-card">
            <div class="status-content">
              <div class="status-icon total">
                <el-icon><Grid /></el-icon>
              </div>
              <div class="status-info">
                <div class="status-value">{{ componentStatus.total }}</div>
                <div class="status-label">总组件数</div>
              </div>
            </div>
          </el-card>
        </el-col>
        <el-col :span="6">
          <el-card class="status-card">
            <div class="status-content">
              <div class="status-icon loaded">
                <el-icon><Check /></el-icon>
              </div>
              <div class="status-info">
                <div class="status-value">{{ componentStatus.loaded }}</div>
                <div class="status-label">已加载</div>
              </div>
            </div>
          </el-card>
        </el-col>
        <el-col :span="6">
          <el-card class="status-card">
            <div class="status-content">
              <div class="status-icon loading">
                <el-icon><Loading /></el-icon>
              </div>
              <div class="status-info">
                <div class="status-value">{{ componentStatus.loading }}</div>
                <div class="status-label">加载中</div>
              </div>
            </div>
          </el-card>
        </el-col>
        <el-col :span="6">
          <el-card class="status-card">
            <div class="status-content">
              <div class="status-icon error">
                <el-icon><WarningFilled /></el-icon>
              </div>
              <div class="status-info">
                <div class="status-value">{{ componentStatus.error }}</div>
                <div class="status-label">错误</div>
              </div>
            </div>
          </el-card>
        </el-col>
      </el-row>
    </div>

    <!-- 主要内容区域 -->
    <div class="main-content">
      <!-- 日历组件 -->
      <div class="component-section">
        <div class="section-header">
          <h2 class="section-title">
            <el-icon><Calendar /></el-icon>
            日历组件
          </h2>
          <div class="section-actions">
            <el-button-group>
              <el-button 
                size="small" 
                @click="loadCalendarComponent"
                :loading="calendarState.loading"
                :disabled="calendarState.isLoaded"
              >
                加载
              </el-button>
              <el-button 
                size="small" 
                @click="unloadCalendarComponent"
                :loading="calendarState.loading"
                :disabled="!calendarState.isLoaded"
              >
                卸载
              </el-button>
              <el-button 
                size="small" 
                @click="reloadCalendarComponent"
                :loading="calendarState.loading"
                :disabled="!calendarState.isLoaded"
              >
                重载
              </el-button>
            </el-button-group>
          </div>
        </div>

        <div class="component-container">
          <div v-if="calendarState.loading" class="loading-placeholder">
            <el-skeleton :rows="3" animated />
          </div>
          <div v-else-if="calendarState.error" class="error-placeholder">
            <el-result
              icon="error"
              :title="calendarState.error"
              sub-title="组件加载失败，请重试"
            >
              <template #extra>
                <el-button type="primary" @click="reloadCalendarComponent">
                  重试
                </el-button>
              </template>
            </el-result>
          </div>
          <div v-else-if="calendarState.isLoaded && calendarState.component" class="component-content">
            <component 
              :is="calendarState.component" 
              v-bind="calendarConfig"
              @mounted="onCalendarMounted"
              @config-updated="onCalendarConfigUpdated"
            />
          </div>
          <div v-else class="empty-placeholder">
            <el-empty description="点击加载按钮来加载日历组件">
              <el-button type="primary" @click="loadCalendarComponent">
                加载组件
              </el-button>
            </el-empty>
          </div>
        </div>
      </div>

      <!-- 天气组件 -->
      <div class="component-section">
        <div class="section-header">
          <h2 class="section-title">
            <el-icon><Sunny /></el-icon>
            天气组件
          </h2>
          <div class="section-actions">
            <el-button-group>
              <el-button 
                size="small" 
                @click="loadWeatherComponent"
                :loading="weatherState.loading"
                :disabled="weatherState.isLoaded"
              >
                加载
              </el-button>
              <el-button 
                size="small" 
                @click="unloadWeatherComponent"
                :loading="weatherState.loading"
                :disabled="!weatherState.isLoaded"
              >
                卸载
              </el-button>
              <el-button 
                size="small" 
                @click="reloadWeatherComponent"
                :loading="weatherState.loading"
                :disabled="!weatherState.isLoaded"
              >
                重载
              </el-button>
            </el-button-group>
          </div>
        </div>

        <div class="component-container">
          <div v-if="weatherState.loading" class="loading-placeholder">
            <el-skeleton :rows="3" animated />
          </div>
          <div v-else-if="weatherState.error" class="error-placeholder">
            <el-result
              icon="error"
              :title="weatherState.error"
              sub-title="组件加载失败，请重试"
            >
              <template #extra>
                <el-button type="primary" @click="reloadWeatherComponent">
                  重试
                </el-button>
              </template>
            </el-result>
          </div>
          <div v-else-if="weatherState.isLoaded && weatherState.component" class="component-content">
            <component 
              :is="weatherState.component" 
              v-bind="weatherConfig"
              @mounted="onWeatherMounted"
              @refreshed="onWeatherRefreshed"
            />
          </div>
          <div v-else class="empty-placeholder">
            <el-empty description="点击加载按钮来加载天气组件">
              <el-button type="primary" @click="loadWeatherComponent">
                加载组件
              </el-button>
            </el-empty>
          </div>
        </div>
      </div>

      <!-- 新闻组件 -->
      <div class="component-section">
        <div class="section-header">
          <h2 class="section-title">
            <el-icon><Document /></el-icon>
            新闻组件
          </h2>
          <div class="section-actions">
            <el-button-group>
              <el-button 
                size="small" 
                @click="loadNewsComponent"
                :loading="newsState.loading"
                :disabled="newsState.isLoaded"
              >
                加载
              </el-button>
              <el-button 
                size="small" 
                @click="unloadNewsComponent"
                :loading="newsState.loading"
                :disabled="!newsState.isLoaded"
              >
                卸载
              </el-button>
              <el-button 
                size="small" 
                @click="reloadNewsComponent"
                :loading="newsState.loading"
                :disabled="!newsState.isLoaded"
              >
                重载
              </el-button>
            </el-button-group>
          </div>
        </div>

        <div class="component-container">
          <div v-if="newsState.loading" class="loading-placeholder">
            <el-skeleton :rows="3" animated />
          </div>
          <div v-else-if="newsState.error" class="error-placeholder">
            <el-result
              icon="error"
              :title="newsState.error"
              sub-title="组件加载失败，请重试"
            >
              <template #extra>
                <el-button type="primary" @click="reloadNewsComponent">
                  重试
                </el-button>
              </template>
            </el-result>
          </div>
          <div v-else-if="newsState.isLoaded && newsState.component" class="component-content">
            <component 
              :is="newsState.component" 
              v-bind="newsConfig"
              @mounted="onNewsMounted"
              @article-clicked="onNewsArticleClicked"
            />
          </div>
          <div v-else class="empty-placeholder">
            <el-empty description="点击加载按钮来加载新闻组件">
              <el-button type="primary" @click="loadNewsComponent">
                加载组件
              </el-button>
            </el-empty>
          </div>
        </div>
      </div>
    </div>

    <!-- 组件配置对话框 -->
    <el-dialog
      v-model="showConfigDialog"
      :title="`配置 ${currentConfigComponent}`"
      width="600px"
    >
      <div class="config-content">
        <el-form
          ref="configFormRef"
          :model="configForm"
          :rules="configRules"
          label-width="120px"
        >
          <el-form-item label="组件配置" prop="config">
            <el-input
              v-model="configForm.config"
              type="textarea"
              :rows="10"
              placeholder="请输入JSON格式的组件配置"
            />
          </el-form-item>
        </el-form>
      </div>
      
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="showConfigDialog = false">取消</el-button>
          <el-button type="primary" @click="saveComponentConfig" :loading="savingConfig">
            保存配置
          </el-button>
        </span>
      </template>
    </el-dialog>
  </div>
</template>

<script setup lang="ts">
/**
 * 首页 - 动态组件使用示例
 * 
 * 功能：
 * 1. 展示如何在页面中使用动态加载的组件
 * 2. 提供组件的加载、卸载、重载功能
 * 3. 支持组件配置和状态管理
 * 4. 提供完整的错误处理和用户反馈
 */

import { ref, computed, onMounted } from 'vue'
import { ElMessage } from 'element-plus'
import { 
  Grid, 
  Refresh, 
  Download, 
  Upload, 
  Calendar,
  Sunny,
  Document,
  Check,
  Loading,
  WarningFilled
} from '@element-plus/icons-vue'
import { useDynamicComponent } from '@/composables/useDynamicComponent'
import type { FormInstance, FormRules } from 'element-plus'

// ==================== 响应式状态 ====================
/** 批量操作状态 */
const loadingAll = ref(false)
const unloadingAll = ref(false)

/** 配置对话框状态 */
const showConfigDialog = ref(false)
const savingConfig = ref(false)
const currentConfigComponent = ref('')

/** 配置表单 */
const configFormRef = ref<FormInstance>()
const configForm = ref({
  config: '{}'
})

/** 配置表单验证规则 */
const configRules: FormRules = {
  config: [
    { required: true, message: '请输入组件配置', trigger: 'blur' },
    {
      validator: (rule: any, value: string, callback: any) => {
        try {
          JSON.parse(value)
          callback()
        } catch (error) {
          callback(new Error('请输入有效的JSON格式'))
        }
      },
      trigger: 'blur'
    }
  ]
}

// ==================== 动态组件管理 ====================
/** 日历组件 */
const {
  component: calendarComponent,
  loading: calendarLoading,
  error: calendarError,
  isLoaded: calendarLoaded,
  loadComponent: loadCalendar,
  unloadComponent: unloadCalendar,
  reloadComponent: reloadCalendar,
  updateConfig: updateCalendarConfig
} = useDynamicComponent('calendar-module', {
  autoLoad: false,
  defaultConfig: {
    theme: 'light',
    showWeekends: true,
    firstDayOfWeek: 1
  },
  onLoaded: (moduleId: string) => {
    console.log(`[HomeView] Calendar component loaded: ${moduleId}`)
    ElMessage.success('日历组件加载成功')
  },
  onError: (error: Error) => {
    console.error('[HomeView] Calendar component error:', error)
    ElMessage.error(`日历组件加载失败: ${error.message}`)
  }
})

/** 天气组件 */
const {
  component: weatherComponent,
  loading: weatherLoading,
  error: weatherError,
  isLoaded: weatherLoaded,
  loadComponent: loadWeather,
  unloadComponent: unloadWeather,
  reloadComponent: reloadWeather,
  updateConfig: updateWeatherConfig
} = useDynamicComponent('weather-module', {
  autoLoad: false,
  defaultConfig: {
    city: '北京',
    unit: 'celsius',
    showForecast: true
  },
  onLoaded: (moduleId: string) => {
    console.log(`[HomeView] Weather component loaded: ${moduleId}`)
    ElMessage.success('天气组件加载成功')
  },
  onError: (error: Error) => {
    console.error('[HomeView] Weather component error:', error)
    ElMessage.error(`天气组件加载失败: ${error.message}`)
  }
})

/** 新闻组件 */
const {
  component: newsComponent,
  loading: newsLoading,
  error: newsError,
  isLoaded: newsLoaded,
  loadComponent: loadNews,
  unloadComponent: unloadNews,
  reloadComponent: reloadNews,
  updateConfig: updateNewsConfig
} = useDynamicComponent('news-module', {
  autoLoad: false,
  defaultConfig: {
    category: 'technology',
    maxArticles: 5,
    showImages: true
  },
  onLoaded: (moduleId: string) => {
    console.log(`[HomeView] News component loaded: ${moduleId}`)
    ElMessage.success('新闻组件加载成功')
  },
  onError: (error: Error) => {
    console.error('[HomeView] News component error:', error)
    ElMessage.error(`新闻组件加载失败: ${error.message}`)
  }
})

// ==================== 组件状态 ====================
/** 组件状态概览 */
const componentStatus = computed(() => {
  const total = 3
  const loaded = [
    calendarLoaded.value,
    weatherLoaded.value,
    newsLoaded.value
  ].filter(Boolean).length
  
  const loading = [
    calendarLoading.value,
    weatherLoading.value,
    newsLoading.value
  ].filter(Boolean).length
  
  const error = [
    calendarError.value,
    weatherError.value,
    newsError.value
  ].filter(Boolean).length
  
  return { total, loaded, loading, error }
})

/** 组件状态对象 */
const calendarState = computed(() => ({
  component: calendarComponent.value,
  loading: calendarLoading.value,
  error: calendarError.value,
  isLoaded: calendarLoaded.value
}))

const weatherState = computed(() => ({
  component: weatherComponent.value,
  loading: weatherLoading.value,
  error: weatherError.value,
  isLoaded: weatherLoaded.value
}))

const newsState = computed(() => ({
  component: newsComponent.value,
  loading: newsLoading.value,
  error: newsError.value,
  isLoaded: newsLoaded.value
}))

// ==================== 组件配置 ====================
/** 日历配置 */
const calendarConfig = ref({
  theme: 'light',
  showWeekends: true,
  firstDayOfWeek: 1
})

/** 天气配置 */
const weatherConfig = ref({
  city: '北京',
  unit: 'celsius',
  showForecast: true
})

/** 新闻配置 */
const newsConfig = ref({
  category: 'technology',
  maxArticles: 5,
  showImages: true
})

// ==================== 生命周期钩子 ====================
/**
 * 组件挂载时初始化
 */
onMounted(async () => {
  console.log('[HomeView] Home view mounted')
  // 可以在这里自动加载某些组件
  // await loadCalendarComponent()
})

// ==================== 批量操作方法 ====================
/**
 * 加载所有组件
 */
async function loadAllComponents() {
  try {
    loadingAll.value = true
    const loadPromises = [
      loadCalendarComponent(),
      loadWeatherComponent(),
      loadNewsComponent()
    ]
    await Promise.allSettled(loadPromises)
    ElMessage.success('所有组件加载完成')
  } catch (error) {
    console.error('Failed to load all components:', error)
    ElMessage.error('部分组件加载失败')
  } finally {
    loadingAll.value = false
  }
}

/**
 * 卸载所有组件
 */
async function unloadAllComponents() {
  try {
    unloadingAll.value = true
    const unloadPromises = [
      unloadCalendarComponent(),
      unloadWeatherComponent(),
      unloadNewsComponent()
    ]
    await Promise.allSettled(unloadPromises)
    ElMessage.success('所有组件卸载完成')
  } catch (error) {
    console.error('Failed to unload all components:', error)
    ElMessage.error('部分组件卸载失败')
  } finally {
    unloadingAll.value = false
  }
}

/**
 * 刷新所有组件
 */
async function refreshAllComponents() {
  const refreshPromises = [
    calendarLoaded.value ? reloadCalendarComponent() : Promise.resolve(),
    weatherLoaded.value ? reloadWeatherComponent() : Promise.resolve(),
    newsLoaded.value ? reloadNewsComponent() : Promise.resolve()
  ]
  await Promise.allSettled(refreshPromises)
  ElMessage.success('所有组件刷新完成')
}

// ==================== 日历组件方法 ====================
/**
 * 加载日历组件
 */
async function loadCalendarComponent() {
  try {
    await loadCalendar()
  } catch (error) {
    console.error('Failed to load calendar component:', error)
  }
}

/**
 * 卸载日历组件
 */
async function unloadCalendarComponent() {
  try {
    await unloadCalendar()
  } catch (error) {
    console.error('Failed to unload calendar component:', error)
  }
}

/**
 * 重载日历组件
 */
async function reloadCalendarComponent() {
  try {
    await reloadCalendar()
  } catch (error) {
    console.error('Failed to reload calendar component:', error)
  }
}

/**
 * 日历组件挂载事件
 */
function onCalendarMounted(config: any) {
  console.log('[HomeView] Calendar component mounted with config:', config)
}

/**
 * 日历组件配置更新事件
 */
function onCalendarConfigUpdated(newConfig: any) {
  console.log('[HomeView] Calendar config updated:', newConfig)
  calendarConfig.value = { ...calendarConfig.value, ...newConfig }
}

// ==================== 天气组件方法 ====================
/**
 * 加载天气组件
 */
async function loadWeatherComponent() {
  try {
    await loadWeather()
  } catch (error) {
    console.error('Failed to load weather component:', error)
  }
}

/**
 * 卸载天气组件
 */
async function unloadWeatherComponent() {
  try {
    await unloadWeather()
  } catch (error) {
    console.error('Failed to unload weather component:', error)
  }
}

/**
 * 重载天气组件
 */
async function reloadWeatherComponent() {
  try {
    await reloadWeather()
  } catch (error) {
    console.error('Failed to reload weather component:', error)
  }
}

/**
 * 天气组件挂载事件
 */
function onWeatherMounted(config: any) {
  console.log('[HomeView] Weather component mounted with config:', config)
}

/**
 * 天气组件刷新事件
 */
function onWeatherRefreshed() {
  console.log('[HomeView] Weather component refreshed')
}

// ==================== 新闻组件方法 ====================
/**
 * 加载新闻组件
 */
async function loadNewsComponent() {
  try {
    await loadNews()
  } catch (error) {
    console.error('Failed to load news component:', error)
  }
}

/**
 * 卸载新闻组件
 */
async function unloadNewsComponent() {
  try {
    await unloadNews()
  } catch (error) {
    console.error('Failed to unload news component:', error)
  }
}

/**
 * 重载新闻组件
 */
async function reloadNewsComponent() {
  try {
    await reloadNews()
  } catch (error) {
    console.error('Failed to reload news component:', error)
  }
}

/**
 * 新闻组件挂载事件
 */
function onNewsMounted(config: any) {
  console.log('[HomeView] News component mounted with config:', config)
}

/**
 * 新闻文章点击事件
 */
function onNewsArticleClicked(article: any) {
  console.log('[HomeView] News article clicked:', article)
  ElMessage.info(`点击了新闻: ${article.title}`)
}

// ==================== 配置管理方法 ====================
/**
 * 打开组件配置对话框
 */
function openConfigDialog(componentName: string, currentConfig: any) {
  currentConfigComponent.value = componentName
  configForm.value.config = JSON.stringify(currentConfig, null, 2)
  showConfigDialog.value = true
}

/**
 * 保存组件配置
 */
async function saveComponentConfig() {
  if (!configFormRef.value) return
  
  try {
    await configFormRef.value.validate()
    savingConfig.value = true
    
    // 解析配置
    const newConfig = JSON.parse(configForm.value.config)
    
    // 根据当前组件更新对应的配置
    switch (currentConfigComponent.value) {
      case '日历组件':
        calendarConfig.value = { ...calendarConfig.value, ...newConfig }
        updateCalendarConfig(calendarConfig.value)
        break
      case '天气组件':
        weatherConfig.value = { ...weatherConfig.value, ...newConfig }
        updateWeatherConfig(weatherConfig.value)
        break
      case '新闻组件':
        newsConfig.value = { ...newsConfig.value, ...newConfig }
        updateNewsConfig(newsConfig.value)
        break
    }
    
    showConfigDialog.value = false
    ElMessage.success('组件配置已保存')
  } catch (error) {
    ElMessage.error('保存配置失败: ' + (error instanceof Error ? error.message : 'Unknown error'))
  } finally {
    savingConfig.value = false
  }
}
</script>

<style scoped>
.home-view {
  padding: 20px;
  background: var(--bg-color);
  min-height: 100vh;
}

/* 页面头部 */
.page-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 30px;
  padding-bottom: 20px;
  border-bottom: 1px solid var(--border-color);
}

.header-content {
  flex: 1;
}

.page-title {
  margin: 0 0 8px 0;
  font-size: 28px;
  font-weight: 600;
  color: var(--text-color);
}

.page-description {
  margin: 0;
  font-size: 16px;
  color: var(--text-color-secondary);
  line-height: 1.5;
}

.header-actions {
  display: flex;
  gap: 12px;
}

/* 状态概览 */
.status-overview {
  margin-bottom: 30px;
}

.status-card {
  border: 1px solid var(--border-color);
  border-radius: var(--radius-md);
  transition: all 0.3s ease;
}

.status-card:hover {
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
}

.status-content {
  display: flex;
  align-items: center;
  gap: 16px;
}

.status-icon {
  width: 48px;
  height: 48px;
  border-radius: var(--radius-md);
  display: flex;
  align-items: center;
  justify-content: center;
  color: white;
}

.status-icon.total {
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
}

.status-icon.loaded {
  background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%);
}

.status-icon.loading {
  background: linear-gradient(135deg, #fa709a 0%, #fee140 100%);
}

.status-icon.error {
  background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);
}

.status-info {
  flex: 1;
}

.status-value {
  font-size: 24px;
  font-weight: 600;
  color: var(--text-color);
  margin-bottom: 4px;
}

.status-label {
  font-size: 14px;
  color: var(--text-color-secondary);
}

/* 主要内容区域 */
.main-content {
  display: flex;
  flex-direction: column;
  gap: 30px;
}

/* 组件区域 */
.component-section {
  border: 1px solid var(--border-color);
  border-radius: var(--radius-md);
  background: var(--card-bg);
  overflow: hidden;
}

.section-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 20px;
  background: var(--bg-color-secondary);
  border-bottom: 1px solid var(--border-color);
}

.section-title {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 0;
  font-size: 20px;
  font-weight: 600;
  color: var(--text-color);
}

.section-actions {
  display: flex;
  gap: 8px;
}

/* 组件容器 */
.component-container {
  padding: 20px;
  min-height: 300px;
}

.loading-placeholder,
.error-placeholder,
.empty-placeholder {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 300px;
}

.component-content {
  width: 100%;
  height: 100%;
}

/* 配置内容 */
.config-content {
  padding: 20px 0;
}

/* 响应式设计 */
@media (max-width: 768px) {
  .home-view {
    padding: 16px;
  }
  
  .page-header {
    flex-direction: column;
    align-items: flex-start;
    gap: 16px;
  }
  
  .status-overview .el-col {
    margin-bottom: 16px;
  }
  
  .section-header {
    flex-direction: column;
    align-items: flex-start;
    gap: 12px;
  }
}

/* 暗色主题适配 */
@media (prefers-color-scheme: dark) {
  .home-view {
    background: var(--bg-color);
  }
  
  .page-header {
    border-color: var(--border-color);
  }
  
  .status-card,
  .component-section {
    background: var(--card-bg);
    border-color: var(--border-color);
  }
  
  .section-header {
    background: var(--bg-color-secondary);
    border-color: var(--border-color);
  }
}
</style>
